package com.leyou.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.dto.PageDTO;
import com.leyou.entity.Sku;
import com.leyou.entity.Spu;
import com.leyou.entity.SpuDetail;
import com.leyou.exception.LyException;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpecParamDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.mapper.SpuMapper;
import com.leyou.service.*;
import com.leyou.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {

    @Autowired
    private CategoryAndBandService categoryAndBandService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SpuService spuService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private SpuDetailService spuDetailService;

    @Autowired
    private SpecParamServiceImpl specParamService;

    @Override
    public PageDTO<SpuDTO> pageQuery(Integer brandId, Integer categoryId, Integer spuId, Integer currentPage, Integer pageSize, Boolean saleable) {
        Page<Spu> spuPage = new Page<>(currentPage,pageSize);

        Page<Spu> page = page(spuPage, new QueryWrapper<Spu>()
                .eq(null!=spuId,"id",spuId)
                .eq(null!=brandId,"brand_id",brandId)
                .eq(null!=categoryId,"cid3",categoryId)
                .eq(null!=saleable,"saleable",saleable));

        PageDTO<SpuDTO> spuDTOPageDTO = new PageDTO<>();
        spuDTOPageDTO.setTotal(page.getTotal());
        spuDTOPageDTO.setTotalPage(page.getPages());
        spuDTOPageDTO.setItems(SpuDTO.convertEntityList(page.getRecords()));

//        List<Long> list = spuDTOPageDTO
//                .getItems()
//                .stream()
//                .map(SpuDTO::getBrandId)
//                .collect(Collectors.toList());


        spuDTOPageDTO.getItems()
                .stream()
                .forEach(spuDTO->{
                    Long id = spuDTO.getBrandId();
                    String name = brandService.getBrandByBrandId(id).getName();
                    spuDTO.setBrandName(name);
                    String categoryName=categoryService.getCategoryByCategoryId(spuDTO.getCid1()).getName()+"/"+
                            categoryService.getCategoryByCategoryId(spuDTO.getCid2()).getName()+"/"+
                            categoryService.getCategoryByCategoryId(spuDTO.getCid3()).getName();

                    spuDTO.setCategoryName(categoryName);

                });


        return spuDTOPageDTO;


    }

    @Override
    public void addGoods(SpuDTO spuDTO) {
        Spu spu = spuDTO.toEntity(Spu.class);

        //添加后默认是下架的状态
        spu.setSaleable(false);
        //存储商品的基本信息
        saveOrUpdate(spu);

        Long spuId = spu.getId();


        if (spuId!= null) {
            //新增spu成功，
            List<SkuDTO> skuDtos = spuDTO.getSkus();
            //存储sku
            skuDtos.stream()
                    .forEach(skuDTO -> {
                        Sku sku = skuDTO.toEntity(Sku.class);
                        sku.setSpuId(spuId);
                        //添加后默认是下架的状态
                        sku.setSaleable(false);
                        skuService.save(sku);
                        });

            //存储skus
//            List<Sku> skus = spuDTO.getSkus().stream()
//                    .map(skuDTO -> {
//                        Sku sku = skuDTO.toEntity(Sku.class);
//                        sku.setSaleable(false);
//                        sku.setSpuId(spuId);
//                        return sku; //将处理好的sku结果重新返回到stream流中
//                    }).collect(Collectors.toList());
//
//            skuService.saveBatch(skus);

            //存储spuDetails
            SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
            SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
            spuDetail.setSpuId(spuId);
            spuDetailService.save(spuDetail);
        }else{
         throw new RuntimeException("新增商品不成功");
        }

    }

    @Override
    public void updateSaleable(Long id, Boolean saleable) {
        if (null != id) {
            //先根据id更改Spu
            Spu spu = getById(id);
            spu.setSaleable(saleable);
            saveOrUpdate(spu);

            //在sku表中根据spu_id更新sku
            skuService.query().eq("spu_id", id).list().stream().forEach(sku -> {
                sku.setSaleable(saleable);
            });

        }else{
            //不处理
        }
    }

    @Override
    public SpuDTO getGoodById(Long id) {

        Spu spu = spuService.getById(id);
        SpuDTO spuDTO = new SpuDTO(spu);
        Long brandId = spuDTO.getBrandId();

        //查询品牌名称
        String brandName = brandService.getBrandByBrandId(brandId).getName();
        spuDTO.setBrandName(brandName);
        //查询分类名称
        String name1 = categoryService.getCategoryByCategoryId(spuDTO.getCid1()).getName();
        String name2 = categoryService.getCategoryByCategoryId(spuDTO.getCid2()).getName();
        String name3 = categoryService.getCategoryByCategoryId(spuDTO.getCid3()).getName();
        String categoryName = name1+"/"+name2+"/"+name3;
        spuDTO.setCategoryName(categoryName);

        //查询spu下面的skus
        List<Sku> skus = skuService.query().eq("spu_id", id).list();
        List<SkuDTO> skuDTOS = SkuDTO.convertEntityList(skus);
        spuDTO.setSkus(skuDTOS);

        //查询spu对应的spudetails
        List<SpuDetail> spuDetails = spuDetailService.query().eq("spu_id", id).list();

        spuDetails.stream().forEach(spuDetail -> {
            spuDTO.setSpuDetail(new SpuDetailDTO(spuDetail));
        });

        return spuDTO;


    }

    @Override
    public void updateGoods(SpuDTO spuDTO) {

        Spu spu = spuDTO.toEntity(Spu.class);
        //根据spu是否包含id，如果包含则更新spu表
        if (spu.getId() != null) {
            boolean success = updateById(spu);
            if (!success) {
                throw new LyException(500,"更新商品失败");
            }
        }

        //更新spuDetail表
        SpuDetailDTO spuDetailDto = spuDTO.getSpuDetail();
        if (spuDetailDto != null && spuDetailDto.getSpuId() != null) {
            SpuDetail spuDetail = spuDetailDto.toEntity(SpuDetail.class);
            boolean success = spuDetailService.updateById(spuDetail);
            if (!success) {
                throw new LyException(500, "更新商品详情表失败");
            }

        }
        /**
         * 思路：先判断有没有id，如果没有则进行增加操作，如果有id再判断是否含有saleable字段，
         * 如果有则进行删除，没有则进行修改
         */
        //更新sku表
        List<SkuDTO> skus = spuDTO.getSkus();
        if (skus != null) {
            for (SkuDTO skuDTO : skus) {
                Sku sku = skuDTO.toEntity(Sku.class);
                if (sku.getId() == null) {
                    //新增操作
                    boolean save = skuService.save(sku);
                    if (!save) {
                        throw new LyException(500, "新增sku失败");
                    }
                }else{
                    //修改或者删除的操作

                    Boolean saleable = sku.getSaleable();

                    if(saleable!=null){
                        //删除操作
                        skuService.removeById(sku.getId());

                    }else{
                        //修改操作
                        skuService.updateById(sku);
                    }

                }

            }
        }


//        //更新spu表
//        Spu spu = spuDTO.toEntity(Spu.class);
//        saveOrUpdate(spu);
//
//        //更新spuDetails表
//        SpuDetailDTO spuDetail = spuDTO.getSpuDetail();
//        SpuDetail spuDetail1 = spuDetail.toEntity(SpuDetail.class);
//        spuDetail.setSpuId(spuDTO.getId());
//        spuDetailService.saveOrUpdate(spuDetail1);
//        //更新sku表
//        List<SkuDTO> skus = spuDTO.getSkus();
//
//        for (SkuDTO skuDTO : skus) {
//
//            skuService.saveOrUpdate(skuDTO.toEntity(Sku.class));
//        }


    }

    @Override
    public SpuDTO getSpuBySpuId(Long id) {
        Spu spu = spuService.getById(id);
        return new SpuDTO(spu);
    }

    @Override
    public List<SpecParamDTO> getAllSpecParamBySpuId(Long id, Boolean searching) {

        Long cid = getById(id).getCid3();

        List<SpecParamDTO> collect = specParamService.getSpecParamDTOSByParams(cid, null, searching)
                .stream()
                .map(specParamDTO -> {
                    //所有specParam模板中的value的json字符串
                    String specification = spuDetailService.getById(id).getSpecification();

                    Map<Long,Object> specMap = JsonUtils.nativeRead(
                            specification,
                            new TypeReference<Map<Long, Object>>() {
                            });

                    specParamDTO.setValue(specMap.get(specParamDTO.getId()));
                    return specParamDTO;
                }).collect(Collectors.toList());

        return collect;


//        ArrayList<SpecParamDTO> specParamDTOS = new ArrayList<>();
//        Spu spu = getById(id);
//
//        //先把categoryIds查出来List<C>
//
//        ArrayList<Long> categoryIds = new ArrayList<>();
//
//        Long brandId = spu.getBrandId();
//        //根据brandId查询到所有的categoryIds集合
//        categoryAndBandService.query().eq(null!=brandId, "brand_id", brandId).list()
//                .stream()
//                .forEach(categoryAndBrand -> {
//                    //
//                    categoryIds.add(categoryAndBrand.getCategoryId());
//                });
//
//        for (Long categoryId : categoryIds) {
//
//            specParamService.query().eq(categoryId!=null,"category_id" ,categoryId ).list()
//                    .stream()
//                    .forEach(specParam -> {
//                        specParamDTOS.add(new SpecParamDTO(specParam));
//                    });
//        }
//
//        return specParamDTOS;



    }
}
